import type { MaybeRefOrGetter } from 'vue'
import { cloneDeep } from 'lodash-es'
import type {
  EnterpriseMonthReportSaveOrUpdateElectric,
  EnterpriseMonthReportSaveOrUpdateElectricParams,
} from '@/types'
import type { ContextMenuData } from '@/components/type'

const errorMark = Symbol('标记是否错误')
const defaultInfo: Omit<
  EnterpriseMonthReportSaveOrUpdateElectric,
  'id'
> = {
  tenantId: '' as any,
  tenantName: '',
  dataTime: '',
  line: '',
  useUnit: '',
  lastValue: '' as any,
  thisValue: '' as any,
  magnification: '' as any,
  usefulElectric: '' as any,
  lineLoss: '' as any,
  countValue: '' as any,
  offset: '' as any,
  realUsefulElectric: '' as any,
  unitPrice: '' as any,
  countPrice: '' as any,
  director: '',
  watchman: '',
  meterReader: '',
  tabulator: '',
}

const countObj: Record<
  string,
  {
    value: number
    index: number
  }
> = {}

export function useHandleElectricity(originalData: MaybeRefOrGetter<EnterpriseMonthReportSaveOrUpdateElectricParams>, time: string) {
  const { $message } = useCurrentInstance()
  const [data, setData]
    = useState<EnterpriseMonthReportSaveOrUpdateElectricParams>(
      [],
    )
  const [info, setInfo] = useState<
    Omit<EnterpriseMonthReportSaveOrUpdateElectric, 'id'>
  >({
    ...defaultInfo,
    dataTime: time,
  })

  watchEffect(() => {
    const _data = cloneDeep(toValue(originalData))
    if (_data.length === 0) {
      setData([
        {
          ...defaultInfo,
          dataTime: time,
        },
      ])
      return
    }
    setInfo(_data.shift()! as any)
    setData(_data)
    classify(_data)
    // console.log(countObj);
  })

  const classify = (
    data: EnterpriseMonthReportSaveOrUpdateElectricParams,
  ) => {
    data.forEach((item) => {
      item.dataTime = time
      const [key, num] = item.line!.split('-')
      if (!num)
        return
      if (!Reflect.has(countObj, key!)) {
        countObj[key!] = {
          value: +num,
          index: 0,
        }
        // return;
      }
      // console.log(countObj);
      if (+num > 1) {
        countObj[key!]!.index = data.findIndex(
          son => son.line === key,
        )
      }
      const max = Math.max(countObj[key!]!.value, +num!)
      // console.log(countObj, max);
      countObj[key!] = {
        value: max,
        index: countObj[key!]!.index,
      }
    })
  }
  const spanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex,
  }: any) => {
    // console.log(rowIndex, countObj);
    // console.log(row, column, rowIndex, columnIndex);
    const [key, num] = row.line!.split('-')
    // ? 线路列处理
    if (columnIndex === 0) {
      // 行合并
      if (
        num
        && rowIndex === (countObj[key]?.index ?? 0) + 1
      ) {
        return {
          rowspan: countObj[key]!.value ?? 1,
          colspan: 1,
        }
      }
      else if (!num) {
        return {
          rowspan: 1,
          colspan: 2,
        }
      }
      else {
        return {
          rowspan: 0,
          colspan: 0,
        }
      }
    }
    // ? 序号列处理
    if (columnIndex === 1) {
      if (!num) {
        return {
          rowspan: 0,
          colspan: 0,
        }
      }
    }

    // console.log(key);

    if (
      [
        'offset',
        'realUsefulElectric',
        'unitPrice',
        'countPrice',
      ].includes(column.property as string)
    ) {
      // console.log(countObj[key], countObj, key, num);
      if (
        num
        && rowIndex === (countObj[key]?.index ?? 0) + 1
      ) {
        return {
          rowspan: countObj[key]!.value ?? 1,
          colspan: 1,
        }
      }
      else if (!num) {
        return {
          rowspan: 1,
          colspan: 1,
        }
      }
      else {
        return {
          rowspan: 0,
          colspan: 0,
        }
      }
    }

    return {
      rowspan: 1,
      colspan: 1,
    }
  }
  const summaryMethod = () => {
    return ['合计', ...Array.from({ length: 9 }).fill(''), '1', '', '2']
  }

  /** 更新关联数据信息 */
  const updateCount = (oldKey: string, newKey: string) => {
    if (!Reflect.has(countObj, oldKey))
      return
    const m = { ...countObj[oldKey]! }
    Reflect.deleteProperty(countObj, oldKey)
    countObj[newKey] = {
      ...m,
    }
    const n = data.value.slice(m.index, m.index + m.value)
    n.forEach(
      item =>
        (item.line = item.line?.replace(oldKey, newKey)),
    )
    // console.log(n);
  }
  /** 更新关联数据行 */
  const updateGroupAssociationValue = <
    T extends keyof EnterpriseMonthReportSaveOrUpdateElectric,
  >(
      key: string,
      prop: T,
      value: EnterpriseMonthReportSaveOrUpdateElectric[T],
    ) => {
    const m = data.value.filter(item =>
      item.line?.includes(key),
    )
    m.forEach(item => (item[prop] = value))
  }

  const isOnly = <
    T extends keyof EnterpriseMonthReportSaveOrUpdateElectric,
  >(
      prop: T,
      value: EnterpriseMonthReportSaveOrUpdateElectric[T],
    ) => {
    const m = data.value
      .map(item => item[prop])
      .filter(Boolean)
    // console.log(m);

    return !m.includes(value)
  }

  const removeRow = (
    row: EnterpriseMonthReportSaveOrUpdateElectric,
  ) => {
    const [key, i] = row.line!.split('-')
    if (Reflect.has(countObj, key!) && !i) {
      $message.warning('请删除子项数据后再执行！')
      return
    }
    const m = new Set(data.value)
    m.delete(row)
    setData([...m])
    // if (i) {
    //   const n = Math.max(
    //     ...data.value
    //       .filter(item => item.line?.includes(`${i}-`))
    //       .map(item => +item.line!.split('-').at(-1)!)
    //   );
    // }
    classify(data.value)
    // console.log(row);
  }
  const appendRow = (
    row: EnterpriseMonthReportSaveOrUpdateElectric,
    son = false,
  ) => {
    const [key] = row.line!.split('-')
    const _index = data.value.indexOf(row)
    const m = { ...defaultInfo }
    const num = key ? countObj[key]?.value ?? 0 : 0
    // console.log(num);

    if (son) {
      const n = data.value
        .filter(item => item.line?.includes(`${key}-`))
        .map(item => +item.line!.split('-').at(-1)!)
      const mi = n.length === 0 ? 0 : Math.max(...n)
      // console.log(n, mi, countObj);

      m.line = `${key}-${mi + 1}`
      data.value.splice(_index + 1, 0, m)
    }
    else {
      data.value.splice(_index + num + 1, 0, m)
    }

    // if (i) {

    // }
    classify(data.value)
    // console.log(m);
  }

  const markErrorState = (
    data: EnterpriseMonthReportSaveOrUpdateElectric,
    bol = true,
  ) => {
    try {
      Reflect.defineMetadata(data, errorMark, bol)
    }
    catch (error) {}
  }
  const getMarkErrorState = (
    data: EnterpriseMonthReportSaveOrUpdateElectric,
  ) => {
    try {
      const m = Reflect.getMetadata(data, errorMark)
      return !!m
    }
    catch (error) {
      return false
    }
  }

  return {
    data,
    info,
    isOnly,
    spanMethod,
    updateCount,
    updateGroupAssociationValue,
    removeRow,
    appendRow,
    summaryMethod,
    markErrorState,
    getMarkErrorState,
  }
}

export const defaultContextMenuData: Partial<ContextMenuData>[]
  = [
    {
      key: 1,
      label: '删除行',
      type: 'danger',
      divider: true,
    },
    {
      key: 2,
      label: '下方添加行',
    },
    {
      key: 3,
      label: '下方添加子项行',
    },
  ]
